Rust miri test error caused by `mlock`, `munlock` and `madvise` of libc
When running cargo +nightly miri test
, encounter the error:
error: unsupported operation: can't call foreign function `mlock` on OS `linux`
This occurs because Miri (Rust’s MIR interpreter) does not fully emulate all system calls or OS-specific functions like mlock
(which locks memory pages to prevent swapping). Miri’s sandboxed environment restricts direct interaction with the OS, causing this error.
Solutions
1. Bypass libc
functions in Tests (Conditional Compilation)
Use Rust’s cfg
attributes to skip mlock
during Miri tests:
// In your code where `mlock` is called:
#[cfg(not(miri))] // Skip this block when running Miri
{
unsafe {
libc::mlock(ptr, len);
}
}
2. Mock libc
functions for Miri
Replacing libc
functions with a no-op allows tests to proceed without triggering errors. For dependencies that require mlock
, create a mock implementation when testing with Miri:
#[cfg(miri)]
mod mock {
// Replace `mlock` with a no-op during Miri tests
#[no_mangle]
pub unsafe extern "C" fn mlock(_addr: *const libc::c_void, _len: libc::size_t) -> libc::c_int {
0 // Return success
}
#[no_mangle]
pub unsafe extern "C" fn munlock(addr: *const libc::c_void, len: libc::size_t) -> libc::c_int {
0
}
#[no_mangle]
pub unsafe extern "C" fn madvise(
addr: *const libc::c_void,
len: libc::size_t,
advice: libc::c_int,
) -> libc::c_int {
0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_with_libc() {
// code
}
}
Key Components: Override mlock
, munlock
, and madvise
with #[no_mangle]